﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Input;

namespace game
{
    public class FreeCamera : Camera
    {
        private Vector3 up;
        private Vector3 look;
        private Vector3 right;

        private float speed = 100;
        private float mouseSpeed = 0.4f;
        public float totalXRotation { get; set; }
        public float totalYRotation { get; set; }
        

        private MouseState mouseState;

        /// <summary>
        /// FreeCamera constructor
        /// </summary>
        /// <param name="Position"></param>
        /// <param name="Target"></param>
        /// <param name="UpVector"></param>
        /// <param name="FieldOfView"></param>
        /// <param name="NearPlaneDistance"></param>
        /// <param name="FarPlaneDistance"></param>
        /// <param name="AspectRatio"></param>
        public FreeCamera(Vector3 Position, Vector3 Target, Vector3 UpVector,
            float FieldOfView, float NearPlaneDistance, float FarPlaneDistance, float AspectRatio)
            : base(Position, Target, UpVector, FieldOfView, NearPlaneDistance, FarPlaneDistance, AspectRatio)
        {
            this.totalXRotation = 0;
            this.totalYRotation = 0;
            this.up = Vector3.Up;
            this.look = Vector3.Forward;
            this.right = Vector3.Right;
            mouseState = Mouse.GetState();
        }

        public override void Update(GameTime gameTime)
        {
            Vector3 rotations = Vector3.Zero; 
            // Keyboard input handling
            
            if (Input.Keyboard.IsKeyDown(Keys.U))
            {
                Position += look * speed;
            }

            if (Input.Keyboard.IsKeyDown(Keys.J))
            {
                Position -= look * speed;
            }

            if (Input.Keyboard.IsKeyDown(Keys.K))
            {
                Position += right * speed;
            }

            if (Input.Keyboard.IsKeyDown(Keys.H))
            {
                Position -= right * speed;
            }

            //if (Input.Keyboard.IsKeyDown(Keys.E))
            //{
            //    rotations.Z -= 0.6f;
            //}

            //if (Input.Keyboard.IsKeyDown(Keys.Q))
            //{
            //    rotations.Z += 0.6f;
            //}


            // Mouse input handling
            MouseState mStateCashe = Input.Mouse;

            rotations.Y -= (mStateCashe.X - mouseState.X) * mouseSpeed;
            rotations.X -= (mStateCashe.Y - mouseState.Y) * mouseSpeed;
            totalXRotation += rotations.X;
            totalYRotation += rotations.Y;

            if (Math.Abs(totalXRotation) >= 75.0f)
            {
                totalXRotation -= rotations.X;
                rotations.X = 0.0f;
            }

            Target = Position + look;

            //Matrix rollMatrix = Matrix.CreateFromAxisAngle(look, MathHelper.ToRadians(rotations.Z));
            //up = Vector3.Transform(up, rollMatrix);
            //right = Vector3.Transform(right, rollMatrix);

            Matrix yawMatrix = Matrix.CreateFromAxisAngle(up, MathHelper.ToRadians(rotations.Y));
            look = Vector3.TransformNormal(look, yawMatrix);
            right = Vector3.TransformNormal(right, yawMatrix);
            
            Matrix pitchMatrix = Matrix.CreateFromAxisAngle(right, MathHelper.ToRadians(rotations.X));
            look = Vector3.TransformNormal(look, pitchMatrix);
            up = Vector3.TransformNormal(up, pitchMatrix);


            UpVector = up;

            UpdateViewMatrix();

            // Reseting up vector
            up = Vector3.Up;
        }
    }
}
